{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "阅读本文大概需要 6.6 分钟。\n",
    "\n",
    "原文：https://fastapi.tiangolo.com/alternatives/\n",
    "\n",
    "作者：tiangolo，FastAPI 的创作者，github star 10.1k\n",
    "\n",
    "翻译：somenzz\n",
    "\n",
    "侵删\n",
    "\n",
    "**APISpec**\n",
    "\n",
    "Marshmallow  和 Webargs 提供以插件形式提供验证，解析和序列化。但文档这块缺失，然后 APISpec 诞生了。APISpec 可做为很多框架的插件（也是做为 Starlette 插件）。\n",
    "\n",
    "它的工作方式是，在 Python 的文档字符串内部使用 YAML 格式的描述来为每一个函数自动生成文档。它会生成 OpenAPI 的 schemas。这也是它工作在 Flask, Starlette, Responder 等框架上的方式。\n",
    "\n",
    "缺点是，我们又必须在 Python 的文档字符串使用   YAML 语法，细微的差别可能导致一些错误。如果我们修改参数或 Marshmallow 的 schema，却忘了还修改 YAML 文档字符串，生成的模式将被废弃。\n",
    "\n",
    "APISpec 和 Marshmallow 的作者是同一个开发者。\n",
    "\n",
    "**启发 FastAPI 地方:**\n",
    "\n",
    "支持 API 的开放式标准。\n",
    "\n",
    "**Flask-apispec**\n",
    "\n",
    "这是一个 Flask 插件，和  Webargs, Marshmallow, APISpec 联系在一起。\n",
    "\n",
    "APISpec 使用 Webargs 和 Marshmallow 生产的信息来生成 OpenAPI 的 schemas。\n",
    "\n",
    "这是一个伟大的工具，非常低估。它应该是比许多 Flask 插件更受欢迎。这可能是由于它的文档过于简洁、抽象。\n",
    "\n",
    "它解决了无需在 Python 文档字符串内编写 YAML（另一种语法）。\n",
    "\n",
    "在 FastAPI 创建之前，Flask, Flask-apispec， Marshmallow ，Webargs 的联合是我经常用到的后端技术栈。使用这些框架，我们创建了几个 Flask 的全栈生成器。以下是是我和几个外部团队一直到现在都使用的主要技术栈：\n",
    "\n",
    "*   https://github.com/tiangolo/full-stack\n",
    "    \n",
    "*   https://github.com/tiangolo/full-stack-flask-couchbase\n",
    "    \n",
    "*   https://github.com/tiangolo/full-stack-flask-couchdb\n",
    "    \n",
    "\n",
    "**启发 FastAPI 地方:**\n",
    "\n",
    "自动生成的 OpenAPI 模式，使用相同的代码定义序列化和验证。\n",
    "\n",
    "**NestJS (and Angular)**\n",
    "\n",
    "这很跟 Python 没有关系，NestJS 是一个 JavaScript（TypeScript）NodeJS 框架，受 Angular 启发。它实现了一些功能，类似的，可以将它们用在 Flask-apispec 上。\n",
    "\n",
    "它具有一个集成的依赖注入系统，同样是受 Angular 启发。像我知道的的其他依赖注入系统一样，它需要预注册，所以，它添加了冗长而重复的代码。\n",
    "\n",
    "由于参数由 TypeScript  类型（就像 Python 的类型提示一样）描述，对编辑器的支持是相当不错的。\n",
    "\n",
    "TypeScript 的数据在编译至 JavaScript 后并不保存，它不能依靠类型来实现验证，序列化和文档。由于这一点，一些设计决策，比如获得的验证，序列化和自动模式生成，它需要在很多地方加装饰器。因此，它变得相当冗长。\n",
    "\n",
    "对于嵌套模式它不能处理的非常好。因此，如果 JSON 体内又有 JSON 对象，这又是嵌套 JSON 对象 JSON 对象，它不能很好的生成文档和验证。\n",
    "\n",
    "**启发 FastAPI 地方**\n",
    "\n",
    "使用 Python 类型提示可以提供很大的编辑器支持。\n",
    "\n",
    "有一个强大的依赖注入系统。找到一种方法，以尽量减少重复的代码。\n",
    "\n",
    "**Sanic**\n",
    "\n",
    "这是首批基于 asyncio 的极端快速 Python 框架之一。它和 Flask 非常相似。\n",
    "\n",
    "它使用的  uvloop 而不是 Python 默认的循环，因此非常快。它启发了 Uvicorn 和 Starlette 的创建，后者在开放的基准方面比 Sanic 还要快。\n",
    "\n",
    "**启发 FastAPI 地方**\n",
    "\n",
    "找到一个拥有极端性能表现的方法。\n",
    "\n",
    "这就是为什么 **FastAPI**基于 Starlette，因为它是目前性能最高的框架（由第三方测试基准）。\n",
    "\n",
    "**Falcon**\n",
    "\n",
    "Falcon 是另一个高性能的 Python 框架，它被设计成微型的做为其他框架的基础，就像 Hug。\n",
    "\n",
    "它使用以前的  WSGI 标准，这是一个同步框架，所以它不能处理像 WebSockets  和其他异步请求，不管怎么说，它仍然有非常好的性能表现。\n",
    "\n",
    "它被设计为具有接收两个参数的函数，一个 “请求” 和一个 “响应”。然后，您从请求中“读取” 部分，并将 “部分”“写入” 响应。由于这种设计，不可能用标准 Python 类型提示将请求参数和主体声明为函数参数。\n",
    "\n",
    "因此，数据验证，序列化和文档编制必须以代码而非自动完成。或者必须像 Hug 框架这样将它们实现为 Falcon 之上。在受 Falcon 设计启发的其他框架中，也是有一个请求对象和一个响应对象作为参数。\n",
    "\n",
    "**启发 FastAPI 地方**\n",
    "\n",
    "寻找获得出色性能的方法。\n",
    "\n",
    "像 Hug（基于 Falcon ） 一样，FastAPI 在函数中声明一个 response 参数。\n",
    "\n",
    "在 FastAPI  这个是可选的，并且主要用于设置 Header，cookie 和备用状态代码。\n",
    "\n",
    "**Molten**\n",
    "\n",
    "我在构建 **FastAPI**的最初阶段发现了 Molten 。它们具有非常相似的想法：\n",
    "\n",
    "*   基于 Python 类型提示。\n",
    "    \n",
    "*   基于这些类型提供验证和生成文档。\n",
    "    \n",
    "*   依赖注入系统。\n",
    "    \n",
    "\n",
    "它没有使用像第三方库（如 Pydantic）提供数据验证，序列化和文档，它有自己的库。因此，这些数据类型定义将不太容易重用。\n",
    "\n",
    "它需要更多详细的配置。并且由于它基于 WSGI（而不是 ASGI），因此其设计目的并不是要利用 Uvicorn，Starlette 和 Sanic 等工具提供的高性能能力。\n",
    "\n",
    "依赖注入系统需要对依赖项进行预注册，并且将基于已声明的类型解决依赖问题。因此，不可能声明多个组件来提供一个特定的类型。\n",
    "\n",
    "路由在一个单独的地方声明，函数在另一个地方使用，（而不是在函数顶部使用装饰器）。比起 Flask（和 Starlette）的实现方式，这更像 Django 的实现方式。它降低了代码之间的耦合程度。\n",
    "\n",
    "**启发 FastAPI 地方**\n",
    "\n",
    "使用模型字段的默认值为数据类型定义额外的验证，对编辑器支持更加友好，在 Pydantic  之前，这是不可行的。\n",
    "\n",
    "这一点实际上也促进了 Pydantic 的部分模块更新，以支持相同的验证声明样式（所有这些功能现在在 Pydantic 中已经可用）。\n",
    "\n",
    "**Hug**\n",
    "\n",
    "Hug 是最早使用 Python 类型提示实现 API 参数类型声明的框架之一。这是一个好主意，启发了其他工具也这样做。\n",
    "\n",
    "它在声明中使用了自定义类型，而不仅是 Python 的标准类型，但这仍然是巨大的进步。\n",
    "\n",
    "它也是第一个生成自定义模式的框架，该自定义模式以 JSON 声明整个 API。\n",
    "\n",
    "它不是基于 OpenAPI 和 JSON Schema 之类的标准。因此，将其与 Swagger UI 等其他工具集成并不是一件容易的事。但这又是一个非常创新的想法。\n",
    "\n",
    "它具有一个有趣而罕见的功能：使用相同的框架，可以创建 API 以及 CLI。\n",
    "\n",
    "由于它基于先前的 Python 同步 Web 框架（WSGI）标准，尽管它仍然具有高性能，但它不能处理 Websockets 和其他事物。\n",
    "\n",
    "**启发 FastAPI 地方**\n",
    "\n",
    "Hug 启发了 APIStar 的各个部分，Hug 与 APIStar 是我发现最有前途的工具之一。\n",
    "\n",
    "Hug 启发了 **FastAPI**使用 Python 类型提示来声明参数，并自动生成定义 API 的模式。\n",
    "\n",
    "Hug 启发了 **FastAPI**在函数中声明一个response 参数在用于设置标头和 cookie。\n",
    "\n",
    "**APIStar（<= 0.5）**\n",
    "\n",
    "在决定构建 **FastAPI**之前，我发现了**APIStar**服务器。它几乎满足了我的所有需求，并且设计出色。\n",
    "\n",
    "这是最早使用 Python 类型提示声明参数和请求的框架之一（在 NestJS 和 Molten 之前）。我在发现 Hub 框架的同时也发现了它。但是 APIStar 使用了 OpenAPI 标准。\n",
    "\n",
    "基于相同的类型提示，它拥有自动化的数据验证，数据序列化和 生成 OpenAPI 的模式。\n",
    "\n",
    "主体模式的定义没有使用 Python 的类型提示，它与 Marshmallow 有点相似，因此，对编辑器的支持不会那么好，但是 APIStar 仍然是最好的选择。它具有最佳性能基准（仅被 Starlette 超越）。\n",
    "\n",
    "最初，它没有自动化 API 文档的 Web UI，但我知道我可以向其中添加 Swagger UI。它有一个依赖注入系统。与上面讨论的其他工具一样，它需要组件的预注册。但是，这仍然是一个很棒的功能。\n",
    "\n",
    "我从未在完整的项目中使用过它，因为它没有安全性集成，因此，我无法用基于 Flask-apispec 的全栈生成器替换我拥有的所有功能。我在项目积压中创建了添加该功能的请求。\n",
    "\n",
    "但是随后，该项目的重点转移了。它不再是一个 API Web 框架，因为创建者需要专注于 Starlette。现在，APIStar 是一组用于验证 OpenAPI 规范的工具，而不是 Web 框架。\n",
    "\n",
    "APIStar 是由 Tom Christie 创建的，他也创建了以下框架：\n",
    "\n",
    "*   Django REST 框架\n",
    "    \n",
    "*   Starlette（FastAPI 所基于的）\n",
    "    \n",
    "*   Uvicorn（由 Starlette 和 FastAPI 使用）\n",
    "    \n",
    "\n",
    "**启发 FastAPI 地方**\n",
    "\n",
    "我认为用相同的 Python 类型声明多个内容（数据验证，序列化和文档），同时又提供了强大的编辑器支持，这是非常绝妙的主意。\n",
    "\n",
    "在长时间寻找相似的框架并测试了许多不同的替代方案之后，APIStar 是最佳的选择。然后，APIStar 不再作为服务器存在，然后 Starlette 出现了，并且为此类系统提供了新的更好的基础。那是构建**FastAPI** 的最终灵感。\n",
    "\n",
    "我认为，FastAPI 是 APIStar 的 “精神上的继任者”，同时基于对所有这些先前工具的学习，在改进和增加功能，键入系统和其他部分的同时，也是如此。\n",
    "\n",
    "**FastAPI 使用的框架**\n",
    "\n",
    "\n",
    "---------------------\n",
    "**Pydantic**\n",
    "\n",
    "Pydantic 是一个库，基于 Python 类型提示来定义数据验证，序列化和文档（使用 JSON 模式）。这使其非常直观。它可与 Marshmallow 媲美。尽管在基准测试中它比 Marshmallow 更快。并且由于它基于相同的 Python 类型提示，因此对编辑器的支持非常棒。\n",
    "\n",
    "**FastAPI 使用它来**处理所有数据验证，数据序列化和自动模型文档（基于 JSON Schema）。\n",
    "\n",
    "然后，**FastAPI**会获取该 JSON Schema 数据并将其放入 OpenAPI 中，除此之外它还会执行其他所有操作。\n",
    "\n",
    "**Starlette**\n",
    "\n",
    "Starlette 是一种轻量级的 ASGI 框架 / 工具包，是构建高性能 asyncio 服务的理想选择。\n",
    "\n",
    "它非常简单直观。它的设计易于扩展，并具有模块化组件。\n",
    "\n",
    "它具有：\n",
    "\n",
    "*   令人印象深刻的性能。\n",
    "    \n",
    "*   WebSocket 支持。\n",
    "    \n",
    "*   GraphQL 支持。\n",
    "    \n",
    "*   处理中的后台任务。\n",
    "    \n",
    "*   启动和关闭事件。\n",
    "    \n",
    "*   测试基于 requests 的客户端。\n",
    "    \n",
    "*   CORS，GZip，静态文件，流式响应。\n",
    "    \n",
    "*   会话和 Cookie 支持。\n",
    "    \n",
    "*   100％ 的测试覆盖率。\n",
    "    \n",
    "*   100％ 类型注释的代码库。\n",
    "    \n",
    "*   零硬依赖性。\n",
    "    \n",
    "\n",
    "Starlette 是目前测试最快的 Python 框架。只有 Uvicorn 超越了它，Uvicorn 不是框架，而是服务器。\n",
    "\n",
    "Starlette 提供了所有基本的 Web 微框架功能。但是它不提供自动数据验证，序列化或 API 文档。\n",
    "\n",
    "这是 **FastAPI**在顶部添加的主要内容之一，全部基于 Python 类型提示（使用 Pydantic）。以及依赖注入系统，安全实用程序，OpenAPI 模式生成等。\n",
    "\n",
    "**技术细节：**ASGI 是 Django 核心团队成员开发的新 “标准”。尽管他们正在这样做，但它仍然不是 “ Python 标准”（PEP）。但是，它已经被多种工具用作 “标准”。这可以大大提高互操作性，因为您可以将 Uvicorn 切换到任何其他 ASGI 服务器（例如 Daphne 或 Hypercorn），也可以添加与 ASGI 兼容的工具，例如 python-socketio。\n",
    "\n",
    "**FastAPI 使用它来**处理所有核心 Web 部件。在顶部添加功能。类 FastAPI 本身直接继承 Starlette。因此，使用 Starlette 可以执行的任何操作，都可以直接使用 FastAPI 进行**。**\n",
    "\n",
    "**Uvicorn**\n",
    "\n",
    "Uvicorn 是基于 uvloop 和 httptools 构建的如闪电般快速的 ASGI 服务器。它不是 Web 框架，而是服务器。例如，它不提供用于按路径进行路由的工具。那是像 Starlette（或 FastAPI）这样的框架可以提供的。它是 Starlette 和 FastAPI 的推荐服务器。\n",
    "\n",
    "**FastAPI 推荐它为**主 Web 服务器运行 **FastAPI**应用程序。您可以将其与 Gunicorn 结合使用，以拥有异步多进程服务器。在 “部署” 部分中查看更多详细信息。\n",
    "\n",
    "（完）\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
